<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      /*
      1. 简单的语法
      ● const 与 let
        特点：生成块级作用域，没有变量提升
        官方规范：https://tc39.es/ecma262/#sec-declarations-and-the-variable-statement
          实际let和const定义的变量是有提升，但是至少在到达变量定义语句之前不能访问

        区别：
          const 定义是常量
          let 定义是变量

        开发中一般使用 const 定义

      ● 解构赋值
        {}
        []
      ● 形参默认值
      ● 扩展运算符: ...
      ● 模板字符串
      ● 对象的属性与方法简写
      ● 模块化语法
      ● ...
      2. 比较复杂的语法
      ● 箭头函数
        箭头函数和普通函数的区别
        this 指向

      ● class 与 extend（引申原型和继承）
        构造函数 + 原型 来继承
        class + extend 来继承

      ● promise / generator / async & await（引申 js 事件循环机制）

        generator 惰性函数（懒），暂停 yield 执行 next

        async & await 
          async函数返回promise对象
          使用 try catch 捕获异常

      ● Proxy（引申 vue2 和 vue3 响应式原理）
        Vue2 响应式通过 Object.defineProperty 实现的，定义原有属性是响应式的，但是新增属性不是响应式
        Vue3 响应式通过 Proxy 实现的，原有和新增属性都是响应式

      ● Map / Set / WeakMap / WeakSet (引申 vue3 响应式原理)
        新的存储数据的结构
          Map 类似于对象，存储key-value的结构，特点：1. 有序 2. key是任意类型
          Set 类似于数组，特点：1. 值是唯一的

          WeakMap 类似于Map，存储key-value的结构，特点：1. 有序 2. key必须是对象类型 3. 一旦key没有外部引用，会自动删除
          WeakSet 类似于Set，特点：1. 值是唯一的 2. 值必须是对象类型 3. 一旦值没有外部引用，会自动删除
      ● ...
    */

      const wMap = new WeakMap();
      let obj = { a: 1 };
      wMap.set(obj, 1);
      console.log(wMap);
      obj = null;
      console.log(wMap);

      // var a = 1;
      // if (true) {
      //   // 暂存性死区
      //   console.log(a); // Uncaught ReferenceError: Cannot access 'a' before initialization
      //   let a;
      // }

      // function fn1() {
      //   debugger;
      //   const a = 1;
      //   // const fn2 = function () {
      //   //   console.log(a);
      //   // };
      //   function fn2() {
      //     console.log(a);
      //   }
      //   console.log(fn2);
      // }
      // fn1();

      function* g() {
        console.log(1);
        yield;
        console.log(2);
        yield;
        console.log(3);
      }

      const iterator = g();
      iterator.next();
      iterator.next();
      iterator.next();
    </script>
  </body>
</html>
